﻿#ifndef QFTPPI_H
#define QFTPPI_H
#include<QTcpSocket>
#include"XQNework.h"
class XQFtpDTP;
//ftp命令发送
class XQFtpPI : public QObject
{
    Q_OBJECT
public:
    XQFtpPI(QObject* parent = 0);
    friend class XQFtp;
    //连接服务器
    void connectToHost(const QString& host, quint16 port);
    //发送命令
    bool sendCommands(const QStringList& cmds);
    //发送命令
    bool sendCommand(const QString& cmd);
    void clearPendingCommands();
    //
    void abort();

    void setDebug(int* debug);
    //是否是指定Debug模式
    bool isDebugModel(Ftp::Debug model);
    //当前命令
    QString currentCommand() const;
    bool rawCommand;
    bool transferConnectionExtended;

    XQFtpDTP* m_dtp=nullptr; // the PI has a DTP which is not the design of RFC 959, but it
    // makes the design simpler this way
signals:
    void connectState(int);
    void finished(const QString&);
    void error(int, const QString&);
    void rawFtpReply(int, const QString&);

private slots:
    void hostFound();
    void connected();
    void connectionClosed();
    void delayedCloseFinished();
    //处理命令返回值
    void readyRead();
    void error(QAbstractSocket::SocketError);

    void dtpConnectState(int);

private:
    // the states are modelled after the generalized state diagram of RFC 959,
    // page 58
    enum State {
        Begin,
        Idle,
        Waiting,
        Success,
        Failure
    };

    enum AbortState {
        None,
        AbortStarted,
        WaitForAbortToFinish
    };

    //返回值处理
    bool processReply();
    //开始下一个cmd命令
    bool startNextCmd();
    int* m_debug=nullptr;//调试模式
    QTcpSocket* m_commandSocket;
    QString m_replyText;
    char m_replyCode[3];
    State m_state;
    AbortState m_abortState;
    QStringList m_pendingCommands;
    QString m_currentCmd;

    bool m_waitForDtpToConnect;//等待连接数据传输通道
    bool m_waitForDtpToClose;//等待关闭数据传输通道

    QByteArray m_bytesFromSocket;

    friend class XQFtpDTP;
};
#endif // !QFtpPrivate_H
